#pragma once

#include <linux/kconfig.h>

#ifdef __ASSEMBLY__
#define __ASM_STR(x)	x
#else
#define __ASM_STR(x)	#x
#endif

#define __REG_SEL(a, b)	__ASM_STR(a)

#define REG_L    __REG_SEL(ld, lw)
#define REG_S    __REG_SEL(sd, sw)
#define REG_SC	 __REG_SEL(sc.d, sc.w)

#ifdef __ASSEMBLY__

/* save all GPs except x1 ~ x5 */
    .macro save_from_x6_to_x31, reg
	REG_S x6,  PT_T1(\reg)
	REG_S x7,  PT_T2(\reg)
	REG_S x8,  PT_S0(\reg)
	REG_S x9,  PT_S1(\reg)
	REG_S x10, PT_A0(\reg)
	REG_S x11, PT_A1(\reg)
	REG_S x12, PT_A2(\reg)
	REG_S x13, PT_A3(\reg)
	REG_S x14, PT_A4(\reg)
	REG_S x15, PT_A5(\reg)
	REG_S x16, PT_A6(\reg)
	REG_S x17, PT_A7(\reg)
	REG_S x18, PT_S2(\reg)
	REG_S x19, PT_S3(\reg)
	REG_S x20, PT_S4(\reg)
	REG_S x21, PT_S5(\reg)
	REG_S x22, PT_S6(\reg)
	REG_S x23, PT_S7(\reg)
	REG_S x24, PT_S8(\reg)
	REG_S x25, PT_S9(\reg)
	REG_S x26, PT_S10(\reg)
	REG_S x27, PT_S11(\reg)
	REG_S x28, PT_T3(\reg)
	REG_S x29, PT_T4(\reg)
	REG_S x30, PT_T5(\reg)
	REG_S x31, PT_T6(\reg)
    .endm

	.macro restore_from_x6_to_x31, reg
	REG_L x6,  PT_T1(\reg)
	REG_L x7,  PT_T2(\reg)
	REG_L x8,  PT_S0(\reg)
	REG_L x9,  PT_S1(\reg)
	REG_L x10, PT_A0(\reg)
	REG_L x11, PT_A1(\reg)
	REG_L x12, PT_A2(\reg)
	REG_L x13, PT_A3(\reg)
	REG_L x14, PT_A4(\reg)
	REG_L x15, PT_A5(\reg)
	REG_L x16, PT_A6(\reg)
	REG_L x17, PT_A7(\reg)
	REG_L x18, PT_S2(\reg)
	REG_L x19, PT_S3(\reg)
	REG_L x20, PT_S4(\reg)
	REG_L x21, PT_S5(\reg)
	REG_L x22, PT_S6(\reg)
	REG_L x23, PT_S7(\reg)
	REG_L x24, PT_S8(\reg)
	REG_L x25, PT_S9(\reg)
	REG_L x26, PT_S10(\reg)
	REG_L x27, PT_S11(\reg)
	REG_L x28, PT_T3(\reg)
	REG_L x29, PT_T4(\reg)
	REG_L x30, PT_T5(\reg)
	REG_L x31, PT_T6(\reg)
	.endm

/* load __global_pointer to gp */
.macro load_global_pointer
.option push
.option norelax
	la gp, __global_pointer$
.option pop
.endm

#endif
